<template>
  <el-dialog
    v-model="dialogVisible"
    :title="dialogTitle"
    width="700px"
    :before-close="close"
    :close-on-click-modal="false"
    destroy-on-close
  >
    <el-scrollbar v-loading="loading" max-height="calc(100vh - 350px)">
      <div style="width: 98%">
        <CustomForm
          ref="formRef"
          :formData="formData"
          :schemas="formSchemas"
          :rules="rules"
          :show-span="true"
          :label-width="120"
          size="default"
        />
      </div>
    </el-scrollbar>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="close">取消</el-button>
        <el-button type="primary" :loading="saveLoading" @click="submit">
          暂存
        </el-button>
        <el-button
          type="success"
          :loading="submitLoading"
          @click="submit('submit')"
        >
          提交
        </el-button>
      </div>
    </template>
    <SelectApprovePerson
      ref="selectApprovePerson"
      @submit="handleSelectPersonSuccess"
    />
  </el-dialog>
</template>

<script setup lang="ts">
import { computed, reactive, ref, toRaw, useTemplateRef } from 'vue'
import {
  getDelayApplicationDetailById,
  IDelayAddOrUpdateRequest,
  saveOrUpdateDelayApplication,
  submitDelayApplication,
} from '@/api/application/delay'
import useFetch from '@/hooks/useFetch'
import CustomForm from '@/components/form/CustomForm.vue'
import useUserStore from '@/stores/user'
import { IFormSchemas } from '@/type/table'
import { FormRules } from 'element-plus'
import { cloneDeep } from 'lodash-es'
import dayjs from 'dayjs'
import SelectApprovePerson from '@/components/approve/SelectApprovePerson.vue'
import { Message } from '@/hooks/message'
import { ESelectApproveUserType } from '@/api/sys/userManage'

const userStore = useUserStore()

const formRef = useTemplateRef<typeof CustomForm>('formRef')
const selectApprovePerson = useTemplateRef<typeof SelectApprovePerson>(
  'selectApprovePerson',
)

const emits = defineEmits(['update'])

const defaultData = {
  applyUnitId: userStore.unitId,
  applyUserId: userStore.id,
  applyUserName: userStore.userName,
  applyUnitName: userStore.unitName,
  applyTime: dayjs().format('YYYY-MM-DD'),
  delayReason: '',
  matterId: undefined,
  delayDay: 1,
  deadlineId: undefined,
  oldDeadline: '',
  approveUserId: undefined,
}

const copyDefaultData = cloneDeep(defaultData)

const formData = reactive<IDelayAddOrUpdateRequest>(defaultData)

const rules = reactive<FormRules<IDelayAddOrUpdateRequest>>({
  delayReason: [{ required: true, message: '请输入申请理由', trigger: 'blur' }],
  delayDay: [{ required: true, message: '请输入延期天数', trigger: 'blur' }],
})
const detailId = ref(undefined)

const formSchemas = computed<IFormSchemas[]>(() => {
  return [
    {
      label: '申请单位',
      prop: 'applyUnitName',
      type: 'input',
      disabled: true,
    },
    {
      label: '申请人',
      prop: 'applyUserName',
      type: 'input',
      disabled: true,
    },
    {
      label: '申请时间',
      prop: 'applyTime',
      type: 'input',
      disabled: true,
    },
    {
      label: '延期天数',
      prop: 'delayDay',
      type: 'input-number',
      componentProps: {
        min: 1,
        max: 9999,
        precision: 0,
      },
    },
    {
      label: '申请理由',
      prop: 'delayReason',
      type: 'input',
      placeholder: '请输入申请理由',
      componentProps: {
        type: 'textarea',
        maxlength: 500,
        clearable: true,
        autosize: { minRows: 4, maxRows: 8 },
        'show-word-limit': true,
      },
    },
  ]
})

const { loading, execute, onFetchSuccess } = useFetch<IDelayAddOrUpdateRequest>(
  getDelayApplicationDetailById,
)

onFetchSuccess((data: IDelayAddOrUpdateRequest) => {
  Object.assign(formData, {
    ...data,
  })
})

const {
  loading: saveLoading,
  execute: saveExecute,
  onFetchSuccess: saveOnFetchSuccess,
} = useFetch(saveOrUpdateDelayApplication)

saveOnFetchSuccess(() => {
  success('暂存成功')
})

const {
  loading: submitLoading,
  execute: submitExecute,
  onFetchSuccess: submitOnFetchSuccess,
} = useFetch(submitDelayApplication)

submitOnFetchSuccess(() => {
  success()
})

function success(message = '提交成功') {
  emits('update')
  close()
  Message({
    message: message,
    type: 'success',
  })
}

const dialogVisible = ref(false)

defineExpose({ show })

const dialogTitle = computed(() => {
  return detailId.value ? '编辑延期申请' : '新增延期申请'
})

/**
 * @param matterInfo 关联事项信息
 * @param id 申请id
 */
async function show(
  matterInfo?: {
    matterId: number
    deadlineId: number
    oldDeadline: string
  },
  id?: number,
) {
  dialogVisible.value = true
  if (id) {
    detailId.value = id
    await execute(id)
  } else {
    // 新增
    Object.assign(formData, matterInfo)
  }
}

function close() {
  dialogVisible.value = false
  Object.assign(formData, copyDefaultData)
  formRef.value?.reset()
  detailId.value = undefined
}

// 提交
async function submit(type = 'save') {
  await formRef.value?.validate(async (valid) => {
    if (valid) {
      if (type === 'submit') {
        selectApprovePerson.value?.show({
          type: ESelectApproveUserType.DELAY,
          applyId: detailId.value,
        })
      } else {
        saveOrSubmit()
      }
    }
  })
}

// 保存或提交
async function saveOrSubmit(type = 'save', approveUserId?: number) {
  const originData = toRaw(formData)
  const postData = {
    ...originData,
    id: detailId?.value ?? undefined,
    applyTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
    approveUserId: approveUserId
      ? approveUserId
      : (originData?.approveUserId ?? undefined),
  }
  type === 'submit'
    ? await submitExecute(postData)
    : await saveExecute(postData)
}

function handleSelectPersonSuccess(approveUserId: number) {
  saveOrSubmit('submit', approveUserId)
}
</script>

<style scoped lang="scss">
:deep(.el-date-editor.el-date-editor--date) {
  --el-date-editor-width: 190px;
  margin-right: 16px;
}
</style>
